import numpy as np
import random
import matplotlib.pyplot as plt
import pandas as pd

N = 150
matrix = []
max_cluster = []   #存储最大团簇坐标
second_cluster = [] #存储次大团簇坐标
a = np.zeros((N, N)) #生成全0矩阵
b = np.zeros((N,N))
c = []

for x in range(N):   #设置二维坐标
    for y in range(N):
        c.append([x, y])

for P in np.arange(0,1,0.01):  #二维数组，设置步长
    for i in range(N):
        for j in range(N):
            if a[i][j] == 10 or a[i][j] == 5:
                a[i][j] = 1
            else:
                continue

    # 初始P=0.1,进行随机撒点
    for i in range(225):
        m = random.choice(c)
        c.remove(m)
        a[m[0],m[1]] = 1
        i = i+1


    # 返回团簇坐标
    class zb:
        def __init__(self, im):
            self.im = im
            m, n = im.shape
            self.mtx = [[0 for _ in range(n)] for _ in range(m)]

        def js(self, i, j, mtx, im):
            m, n = im.shape
            return i >= 0 and i < m and j >= 0 and j < n and mtx[i][j] == 0 and im[i][j] == 1

        def add(self, i, j, mtx, im, q):
            if self.js(i, j, mtx, im):
                q.append([i, j])
                self.mtx[i][j] = 1

        #遍历
        def bl(self):
            m, n = self.im.shape
            tc = []
            for i in range(m):
                for j in range(n):
                    if self.mtx[i][j] == 1 or self.im[i][j] == 0:
                        continue
                    P, Q = list(), list()
                    P.append([i, j])
                    self.mtx[i][j] = 1
                    while P:
                        d = P.pop(0)
                        Q.append(d)
                        self.add(d[0] - 1, d[1], self.mtx, a, P)
                        self.add(d[0] + 1, d[1], self.mtx, a, P)
                        self.add(d[0], d[1] - 1, self.mtx, a, P)
                        self.add(d[0], d[1] + 1, self.mtx, a, P)
                    tc.append(Q)
            return tc
# 计算
    s = zb(a)
    tc = s.bl()
    max_tc_index = tc.index(max(tc, key=len))
    # 找最大团簇并改变最大团簇的值，方便作图
    for m in tc[max_tc_index]:
        a[m[0]][m[1]] = 10
    # 删除最大团簇，方便寻找次大团簇
    middle = tc[max_tc_index]
    tc.remove(tc[max_tc_index])
    # 寻找次大团簇并改变次大团簇的值，方便作图
    if tc == []:
        second_tc_index = 0
    else:
        second_tc_index = tc.index(max(tc, key=len))
        for m in tc[second_tc_index]:
            a[m[0]][m[1]] = 5
    # 将最大团簇的值加回去
    tc.append(middle)

    cen = []
    for i in range(len(tc)):
        x = tc[i]
        cenx = [x_[0] for x_ in x]
        ceny = [x_[1] for x_ in x]
        cen.append([sum(cenx) / len(cenx), sum(ceny) / len(ceny)])

    # 绘制团簇生长的图
    print(a)
    plt.figure(0)
    plt.imshow(a,origin='lower') #设置lower参数绘图才不会反
    plt.pause(0.5)

    number = []
    # 统计每个团簇的大小
    for i in range(len(tc)):
        number.append(len(tc[i]))

    new_number = np.copy(number)
    if P < 0.59:
        print('P为{}时的团簇大小分布为：\n'.format(P))
        arr_p = new_number.flatten()  # 数组转为1维
        arr_p = pd.Series(arr_p)  # 转换数据类型
        arr_p = arr_p.value_counts()  # 计数
        arr_p.sort_index(inplace=True)  # 按照团簇大小排序
        print(arr_p)
    else:
        delete_number = np.delete(new_number, np.where(new_number.max()))
        print('P为%.2f时的团簇大小分布为：\n' % P)
        arr_p = delete_number.flatten()  # 数组转为1维
        arr_p = pd.Series(arr_p)  # 转换数据类型
        arr_p = arr_p.value_counts()  # 计数
        arr_p.sort_index(inplace=True)  # 按照团簇大小排序
        print(arr_p)

    average_number = np.mean(number)
    matrix.append(average_number)
    max_cluster.append(max(number))
    number.remove(max(number))
    if number != []:
        second_cluster.append(max(number))
    else:
        second_cluster.append(0)

print("最大团簇为:")
count=0 #设置初始计数
for k1 in max_cluster:
    print(k1, end=' ')
    count += 1 #开始计数
    if count % 10 == 0: #每10个换行
        print(end='\n')
print('\n')

print("次大团簇为:")
count2=0 #设置初始计数
for k2 in second_cluster:
    print(k2, end=' ')
    count2 += 1 #开始计数
    if count2 % 10 == 0: #每10个换行
        print(end='\n')
#print("最大团簇为:",max_cluster)
#print("次大团簇为:",second_cluster)

x_data = [x for x in range(0,25000,250)]
#max_cluster.reverse()
#second_cluster.reverse()
plt.rcParams['font.sans-serif']=['SimHei'] #解决z中文显示为方块的问题
plt.title("团簇随p变化情况")  # 设置标题及字体
plt.xlabel("概率p的25000倍")
plt.plot(x_data,max_cluster,color='red',label="最大团簇")
plt.plot(x_data,second_cluster,color='blue',label="次大团簇",linestyle='--')
plt.legend()
plt.show()
